<template>
  <q-select v-model='state.province' :label='sendOrReceive+"省市区"' :options='options.provinces'
            :rules='rules.province' />
  <q-select v-model='state.city' :label='sendOrReceive+"地级市"' :options='options.cities' :rules='rules.city' />
  <q-select v-model='state.district' :label='sendOrReceive+"区县"' :options='options.districts' :rules='rules.district' />
  <q-input v-model='state.detail' :label='sendOrReceive+"详细地址"' :rules='rules.detail' />
</template>


<script lang='ts'>
/* eslint-disable @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call */

import { computed, defineComponent, ref, watch } from 'vue';
import { required } from 'src/services/validator';


export default defineComponent({
  name: 'AddressInput',
  props: {
    sendOrReceive: {
      type: String,
      required: true
    },
    address: {
      type: String,
      required: true
    },
    longitude: {
      type: Number,
      required: true
    },
    latitude: {
      type: Number,
      required: true
    }
  },
  emits: ['update:address', 'update:longitude', 'update:latitude'],
  setup(props, { emit }) {
    AMap.plugin(['AMap.DistrictSearch', 'AMap.Geocoder'], Function);
    const DistrictSearch = new AMap.DistrictSearch();
    const Geocoder = new AMap.Geocoder();

    const options = ref({
      provinces: [] as string[],
      cities: [] as string[],
      districts: [] as string[]
    });

    const state = ref({
      province: '',
      city: '',
      district: '',
      detail: ''
    });

    const rules = {
      province: [(val: string | undefined) => required(val, '请选择省市区')],
      city: [(val: string | undefined) => required(val, '请选择地级市')],
      district: [(val: string | undefined) => required(val, '请选择区县')],
      detail: [(val: string | undefined) => required(val, '请输入详细地址')]
    };


    DistrictSearch.search('中国', function(status, result) {
      options.value.provinces = (result as AMap.DistrictSearch.SearchResult)
        .districtList[0].districtList?.map(district => district.name) ?? [];
    });

    watch(() => state.value.province, () => {
      if (state.value.province !== '') {
        DistrictSearch.search(state.value.province, function(status, result) {
          options.value.cities = (result as AMap.DistrictSearch.SearchResult)
            .districtList[0].districtList?.map(district => district.name) ?? [];
        });
        options.value.districts = [];
        state.value.city = '';
        state.value.district = '';
      }
    });

    watch(() => state.value.city, () => {
      if (state.value.city !== '') {
        DistrictSearch.search(state.value.city, function(status, result) {
          options.value.districts = (result as AMap.DistrictSearch.SearchResult)
            .districtList[0].districtList?.map(district => district.name) ?? [];
        });
        state.value.district = '';
      }
    });

    const address = computed(() => state.value.province + state.value.city + state.value.district + state.value.detail);

    watch(() => address.value, () => {
      emit('update:address', address.value);
      let latitude = 0;
      let longitude = 0;
      Geocoder.getLocation(address.value, function(status, result) {
        if (status === 'complete' && (result as AMap.Geocoder.GeocodeResult).geocodes.length) {
          const coordinate = (result as AMap.Geocoder.GeocodeResult).geocodes[0].location;
          latitude = coordinate.getLat();
          longitude = coordinate.getLng();
        }
        emit('update:latitude', latitude);
        emit('update:longitude', longitude);
      });
    });

    return {
      state,
      options,
      rules
    };
  }
});
</script>
<style scoped lang='scss'>
.q-select, .q-input {
  width: 23.7%;
}

</style>
